home *** CD-ROM | disk | FTP | other *** search
/ The CICA Windows Explosion! / The CICA Windows Explosion! - Disc 2.iso / programr / flute.zip / SAMP_ACT.C / WINDACTS.C < prev    next >
C/C++ Source or Header  |  1995-04-05  |  15KB  |  527 lines

  1. ///////////////////////////////////////////////////////////////////////////
  2. // WindActs.c
  3. // Code to help programs manipulate Fluid arrays and implement Window Acts
  4.  
  5. #include    "windows.h"
  6. #include    "windacts.h"
  7. #include    <string.h>
  8.  
  9. #define        sizearray    4
  10. #define        sizenullstring 4
  11.  
  12. //#pragma warning(disable:4047 4024 4047)
  13.  
  14. ////////////////////////////// general functions //////////////////////////
  15. /* calculate the size of a CeSk data object given a ptr */
  16. /* to data variable in op1 */
  17. /* return the size IN BYTES as a function return */
  18. long GetVarSize(DataObj  FAR *op1)
  19. {
  20.     short   i,j;
  21.     long k,l;
  22.     DataObj FAR *op2;
  23.                                     
  24.     switch  (op1->tint.vtype) {
  25.         case NULLTYPE :
  26.                 return (sizeof(IntObj));
  27.         case INTTYPE:
  28.                 return (sizeof(IntObj));
  29.         case FLOATTYPE:
  30.                 return (sizeof(FloatObj));
  31.         case DOUBLETYPE:
  32.                 return (sizeof(DoubleObj));
  33.         case STRINGTYPE:
  34.                 return ((op1->tstring.length+5) & ~1);
  35.         case BOOLTYPE:
  36.                 return (sizeof(BoolObj));
  37.         case ERRORTYPE:
  38.                 return ((op1->terror.length+5) & ~1); 
  39.         case DATETYPE:
  40.                 return (sizeof(DateObj));
  41.         case HMSTYPE:
  42.                 return (sizeof(HmsObj));
  43.         case COMPLEXTYPE:
  44.                 return (sizeof(ComplexObj));
  45.         case EQUATIONTYPE:
  46.                 return ((op1->tequation.length+5) & ~1); 
  47.         case ARRAYTYPE:
  48.                 op2=PtrContent(op1);
  49.                 j= op1->tarray.elements; k=4;
  50.                 for (i=0; i<j; i++) {
  51.                         l=GetVarSize(op2);
  52.                         k+=l;
  53.                         op2 = (DataObj *)(((char *)(op2)) +l);
  54.                 };
  55.                 return k;
  56.     };
  57.         
  58. };
  59.  
  60. /* register a given string as a window message */
  61. /* Input: msgid - the id of the resource to the string */
  62. /* Return: a UINT representing the registered window message */
  63. UINT    RegisterResourceString(HINSTANCE hInst, UINT msgid)
  64. {
  65.     char    text[256];
  66.     
  67.     LoadString(hInst,msgid,text,sizeof(text));
  68.     if (!text[0]) return NULL;
  69.     return RegisterWindowMessage(text);
  70. };
  71.  
  72. /* construct a two dimensional CeSk array containing the strings */
  73. /* required for a ActList command */
  74. /* Input: baseID - the base string ID to start from, the strings */
  75. /*      are assumed to be string resource pairs starting at baseID */
  76. /*      and terminated with a string */
  77. /* Returns a HGLOBAL to the array, the HGLOBAL is allocated as shared */
  78. HGLOBAL ProduceActList(HINSTANCE hInst, UINT baseID)
  79. {
  80.     long    blocksize,writeptr,len;
  81.     HGLOBAL result;
  82.     DataObj    FAR *op1,FAR *op2;
  83.     char    text[256],text2[256];
  84.     unsigned short    count;
  85.  
  86.     blocksize=1024;
  87.     writeptr=4;    /* sizearray is size of array header =4 bytes*/
  88.     result=GlobalAlloc(GMEM_DDESHARE,blocksize);
  89.     if (!result) return 0;
  90.     op1=DataGlobalLock(result);
  91.     op1->tarray.vtype=ARRAYTYPE;
  92.     op1->tarray.elements=0;
  93.     count=0;
  94.     GlobalUnlock(result);
  95.  
  96.     do {
  97.         LoadString(hInst,baseID++,text,sizeof(text));
  98.         if (text[0]=='!' && !text[1]) break;        // reached the end
  99.         LoadString(hInst,baseID++,text2,sizeof(text2));
  100.         len=strlen(text)+strlen(text2)+sizearray+sizenullstring*2;
  101.         if (len+32+writeptr > blocksize) {
  102.             HGLOBAL    newresult;
  103.             /* expand the block */
  104.             blocksize=1024+len+writeptr;
  105.             newresult=GlobalReAlloc(result,blocksize,0);
  106.             if (!newresult) {
  107.                 GlobalFree(result);
  108.                 return 0;
  109.             };
  110.             result=newresult;
  111.         };
  112.         op1=DataGlobalLock(result);
  113.         op2=op1=StepBytes(op1,writeptr);
  114.         op1->tint.vtype=ARRAYTYPE;
  115.         op1->tarray.elements=2;
  116.         op1=PtrContent(op1);
  117.         op1->tstring.vtype=STRINGTYPE;
  118.         op1->tstring.length=strlen(text);
  119.         memcpy(op1->tstring.value,text,op1->tstring.length);
  120.         op1=NextDataObj(op1);
  121.         op1->tstring.vtype=STRINGTYPE;
  122.         op1->tstring.length=strlen(text2);
  123.         memcpy(op1->tstring.value,text2,op1->tstring.length);
  124.         writeptr+=GetVarSize(op2);
  125.         GlobalUnlock(result);
  126.         count++;
  127.     } while (TRUE);
  128.     op1=DataGlobalLock(result);
  129.     op1->tarray.elements=count;
  130.     GlobalUnlock(result);
  131.     result=GlobalReAlloc(result,writeptr,0);
  132.     return result;
  133. };
  134.  
  135. /* register a list of functions as window messages */
  136. /* Input: */
  137. /*      hInst - handle of the instance containing the resource strings */
  138. /*    baseID - the base string ID to start from, the functions are */
  139. /*      assumed to be in pairs, the first string in a pair is the function */
  140. /*      name, the second a help string explaining what is does */
  141. /*      messID[] - ptr to array of UINTs to receive the results */
  142. void    RegisterActList(HINSTANCE hInst, UINT baseID,UINT FAR * messID)
  143. {
  144.     short    count;
  145.     char    temp[256];
  146.  
  147.     count=0;
  148.     do {
  149.         LoadString(hInst,baseID,temp,sizeof(temp));
  150.         if (temp[0]=='!' && !temp[1]) break;
  151.         messID[count++]=RegisterWindowMessage(temp);
  152.         baseID+=2;
  153.     } while (TRUE);
  154.     return;
  155. };
  156.  
  157. // given a window act id, find the corresponding name of the act
  158. // This is a complimentary function to RegisterActList
  159. // Input: hInst - the handle of the instance
  160. //          ActId - the ID of the Window act to search for
  161. //          baseID - the base id of the strings for window acts
  162. //          pBuff - ptr to the buffer to receive the act name
  163. //          len - length of the buffer in bytes
  164. // The pBuff is filled with the name of the Act (or "" if none)
  165. void FindActName(HINSTANCE hInst, UINT ActId, UINT baseID, LPSTR pBuff, int len)
  166. {
  167.     short    count;
  168.     int        i;
  169.     char    temp[256];
  170.  
  171.     count=0;
  172.     do {
  173.         LoadString(hInst,baseID,temp,sizeof(temp));
  174.         if (temp[0]=='!' && !temp[1]) {
  175.             pBuff[0]=0;
  176.             return;
  177.         };
  178.         if (ActId==RegisterWindowMessage(temp)) {
  179.             // we found a match
  180.             for (i=0; i<(len-1) && temp[i]; i++) pBuff[i]=temp[i];
  181.             pBuff[i]=0;
  182.             return;
  183.         };
  184.         baseID+=2;
  185.     } while (TRUE);
  186.     return;
  187. };
  188.  
  189.  
  190. //////////////////// functions to set the FluteNames of windows ////////////////
  191. static    ATOM FluteNameGAtom=0;
  192.  
  193. // set the "Flute Name" for a window. The Flute name is stored in a property
  194. // Input: hWnd - handle of the window
  195. //          lpBuff - ptr to name to assign to the window
  196. void SetWindowFluteName(HWND hWnd, LPCSTR lpBuff)
  197. {
  198.     ATOM    nAtom;
  199.  
  200.     if (!FluteNameGAtom) FluteNameGAtom = GlobalAddAtom("FluteName");
  201.     nAtom = GlobalAddAtom(lpBuff);
  202.     
  203.     SetProp(hWnd, (LPCSTR)FluteNameGAtom, (HANDLE)nAtom);
  204. };
  205.  
  206. // set the "Flute Name" for an item on a dialogue.
  207. // Input: hDlg - handle of the dialogue
  208. //          id - id of the dialogue item
  209. //          lpBuff - ptr to the name to assign
  210. void SetDlgItemFluteName(HWND hDlg, UINT id, LPCSTR lpBuff)
  211. {
  212.     SetWindowFluteName(GetDlgItem(hDlg,id),lpBuff);
  213. };
  214.  
  215. // Clear a "FluteName" from a window
  216. // Input: hWnd - handle of the window whose Flute name is to be cleared
  217. void ClearWindowFluteName(HWND hWnd)
  218. {
  219.     ATOM    pat;
  220.     // SetWindowFluteName must have been called previously, so
  221.     // FluteNameGAtom *must* exist if there are any Flute names to delete
  222.     if (!FluteNameGAtom) return;
  223.     pat = (ATOM)GetProp(hWnd, (LPCSTR)FluteNameGAtom);
  224.     if (pat) GlobalDeleteAtom(pat);
  225.     RemoveProp(hWnd, (LPCSTR)FluteNameGAtom);
  226. };
  227.  
  228. // Clear the "FluteName" from all windows on a dialogue
  229. // Input: hDlg - handle of the dialogue whose names are to be cleared
  230. void ClearDlgItemFluteNames(HWND hDlg)
  231. {
  232.     HWND    hw;
  233.     
  234.     hw= GetWindow(hDlg,GW_CHILD);
  235.     while (hw) {
  236.         ClearWindowFluteName(hw);
  237.         hw = GetWindow(hDlg,GW_HWNDNEXT);
  238.     };
  239. };
  240.  
  241. //////////////////// Data construction Functions ////////////////////////////
  242.  
  243. // Make a string object given a ptr to a null terminated C string
  244. // Input: lpBuff - ptr to the text
  245. // Output: HGLOBAL for a StringObj containing the text
  246. HGLOBAL    MakeString(LPCSTR lpBuff)
  247. {
  248.     UINT    len;
  249.     HGLOBAL    result;
  250.     DataObj    FAR *pos;
  251.     
  252.     for (len=0; lpBuff[len]; len++);
  253.     result = GlobalAlloc(GMEM_DDESHARE, (5+len) & ~1);
  254.     if (!result) return result;
  255.     
  256.     pos=DataGlobalLock(result);
  257.     pos->tstring.vtype=STRINGTYPE;
  258.     pos->tstring.length = len;
  259.     for (len=0; lpBuff[len]; len++) pos->tstring.value[len]=lpBuff[len];
  260.     GlobalUnlock(result);
  261.     
  262.     return result;
  263. };
  264.  
  265. // Given a string resource ID, produce an Error Object (contained in a handle)
  266. // Input: hInst - Instance of the program that owns the string resource
  267. //          id  - id of the string
  268. // Output: HGLOBAL containing an ErrorObject
  269. HGLOBAL    GeneralError(HINSTANCE hInst, UINT id)
  270. {
  271.     HGLOBAL    result;
  272.     char    text[256];
  273.     DataObj    FAR *pos;
  274.     
  275.     LoadString(hInst,id,text,sizeof(text));
  276.     result = MakeString(text);
  277.     if (!result) return NULL;
  278.     pos=DataGlobalLock(result);
  279.     pos->terror.vtype = ERRORTYPE;
  280.     GlobalUnlock(result);
  281.     return result;
  282. }
  283.  
  284. // Given a long return a Flute integer object (Flute integers are longs)
  285. // Input: lval - the long to convert
  286. // Output: HGLOBAL containing an integer object
  287. HGLOBAL MakeInt(long lval)
  288. {
  289.     HGLOBAL    result;
  290.     DataObj    FAR *pos;
  291.     
  292.     result = GlobalAlloc(GMEM_DDESHARE,sizeof(IntObj));
  293.     pos=DataGlobalLock(result);
  294.     pos->tint.vtype = INTTYPE;
  295.     pos->tint.value = lval;
  296.     GlobalUnlock(result);
  297.     
  298.     return result;
  299. };
  300.  
  301. // Given a double, produce a Flute double object in a HGLOBAL
  302. // Input: dval - the value to convert
  303. // Output: A HGLOBAL containing the value
  304. HGLOBAL MakeDouble(double dval)
  305. {
  306.     HGLOBAL    result;
  307.     DataObj    FAR *pos;
  308.     
  309.     result = GlobalAlloc(GMEM_DDESHARE,sizeof(DoubleObj));
  310.     pos=DataGlobalLock(result);
  311.     pos->tdouble.vtype = DOUBLETYPE;
  312.     pos->tdouble.value = dval;
  313.     GlobalUnlock(result);
  314.     
  315.     return result;
  316. };
  317.  
  318. // Return a NULL object inside a HGLOBAL
  319. HGLOBAL NullObj()
  320. {
  321.     HGLOBAL    result;
  322.     DataObj    FAR *pos;
  323.     
  324.     result = GlobalAlloc(GMEM_DDESHARE,sizeof(IntObj));
  325.     pos=DataGlobalLock(result);
  326.     pos->tint.vtype = NULLTYPE;
  327.     pos->tint.value = 0l;
  328.     GlobalUnlock(result);
  329.     
  330.     return result;
  331. };
  332.  
  333. //////////////////// Data Extraction Functions //////////////////////////
  334.  
  335. // Given a FAR ptr to a Flute data object, extract a long value
  336. // This will convert any NUMERIC value into a long
  337. // Input: optr - ptr to the object
  338. //          pTrans - ptr to a BOOLEAN which will is set on return
  339. // Output: a long value contained within the object
  340. //           The boolean pointed to by pTrans is set TRUE if successfully translated
  341. long GetALong(DataObj FAR *optr, BOOL FAR *pTrans)
  342. {
  343.     switch  (optr->tint.vtype) {
  344.         case NULLTYPE :
  345.                 *pTrans = TRUE;
  346.                 return 0l;
  347.         case INTTYPE:
  348.                 *pTrans = TRUE;
  349.                 return optr->tint.value;
  350.         case FLOATTYPE:
  351.                 *pTrans = TRUE;
  352.                 return (long)optr->tfloat.value;
  353.         case DOUBLETYPE:
  354.                 *pTrans = TRUE;
  355.                 return (long)optr->tdouble.value;
  356.         case BOOLTYPE:
  357.                 *pTrans = TRUE;
  358.                 return (long)optr->tboolean.value;
  359.         case COMPLEXTYPE:
  360.                 *pTrans = TRUE;
  361.                 return (long)optr->tcomplex.realpart;
  362.         case ARRAYTYPE:
  363.         case DATETYPE:
  364.         case ERRORTYPE:
  365.         case STRINGTYPE:
  366.         case HMSTYPE:
  367.         case EQUATIONTYPE:
  368.                 *pTrans = FALSE;
  369.                 return 0;
  370.     };
  371.     return 0;
  372. };
  373.  
  374. // Given a FAR ptr to a Flute data object, extract a double value
  375. // Input: optr - ptr to the object
  376. //          pTrans - ptr to a BOOLEAN which will be filled on return
  377. // Output: a double value
  378. //            The Boolean pointed to by pTrans is set TRUE if successfully translated
  379. double GetADouble(DataObj FAR *optr, BOOL FAR *pTrans)
  380. {
  381.     switch  (optr->tint.vtype) {
  382.         case INTTYPE:
  383.                 *pTrans = TRUE;
  384.                 return (double)optr->tint.value;
  385.         case FLOATTYPE:
  386.                 *pTrans = TRUE;
  387.                 return (double)optr->tfloat.value;
  388.         case DOUBLETYPE:
  389.                 *pTrans = TRUE;
  390.                 return (double)optr->tdouble.value;
  391.         case BOOLTYPE:
  392.                 *pTrans = TRUE;
  393.                 return (double)optr->tboolean.value;
  394.         case COMPLEXTYPE:
  395.                 *pTrans = TRUE;
  396.                 return (double)optr->tcomplex.realpart;
  397.         case ARRAYTYPE:
  398.         case DATETYPE:
  399.         case ERRORTYPE:
  400.         case NULLTYPE :
  401.         case STRINGTYPE:
  402.         case HMSTYPE:
  403.         case EQUATIONTYPE:
  404.                 *pTrans = FALSE;
  405.                 return 0;
  406.     };
  407.     return 0;
  408. };
  409.  
  410. // Given a ptr to a data object, fill a character buffer
  411. // containing the string or error object text
  412. // Input: optr - ptr to the object
  413. //          pTrans - ptr to a BOOLEAN which is filled on return
  414. //          pBuff - ptr to the destination buffer
  415. //          len - length of buffer
  416. void GetAString(DataObj FAR *optr, BOOL FAR *pTrans, char FAR *pBuff, UINT len)
  417. {
  418.     UINT    slen,i;
  419.  
  420.     if (!len) {
  421.         *pTrans=FALSE;
  422.         return;
  423.     };
  424.     switch (optr->tint.vtype) {
  425.         case ERRORTYPE:
  426.         case STRINGTYPE:
  427.             slen = optr->tstring.length;
  428.             if (slen > (len-1)) slen = len-1;
  429.             for (i=0; i<slen; i++) pBuff[i]=optr->tstring.value[i];
  430.             *pTrans=TRUE;
  431.             pBuff[slen]=0;
  432.             return;
  433.         default:
  434.             *pBuff = 0;
  435.             *pTrans = FALSE;
  436.             return;
  437.     };
  438. };
  439.  
  440. ////////////////////////// Array assembly functions //////////////////////////////////
  441.  
  442. // make an N element Flute array from a table of N HGLOBALs
  443. // Input: pHands - ptr to the array of HGLOBALs that contain data objects
  444. //          N - number of elements
  445. // Output: a HGLOBAL to a Flute array
  446. // NOTE: THE HANDLES PASSED IN pHand ARE FREED BY THIS FUNCTION
  447. HGLOBAL MakeArrayN(HGLOBAL FAR *pHands, UINT N)
  448. {
  449.     UINT    i;
  450.     DataObj FAR *pobd, FAR *pobs;
  451.     HGLOBAL    result;
  452.     long    len;
  453.     
  454.     len=0;
  455.     for (i=0; i<N; i++) {
  456.         pobs = DataGlobalLock(pHands[i]);
  457.         len+=GetVarSize(pobs);
  458.         GlobalUnlock(pHands[i]);
  459.     };
  460.     
  461.     result= GlobalAlloc(GMEM_DDESHARE,len+4);
  462.     if (result) {
  463.         pobd = DataGlobalLock(result);
  464.         pobd->tarray.vtype = ARRAYTYPE;
  465.         pobd->tarray.elements=(short)N;
  466.         
  467.         pobd = PtrContent(pobd);
  468.         for (i=0; i<N; i++) {
  469.             pobs = DataGlobalLock(pHands[i]);
  470.             hmemcpy(pobd, pobs, GetVarSize(pobs));
  471.             pobd = NextDataObj(pobd);
  472.             GlobalUnlock(pHands[i]);
  473.         };
  474.     };
  475.     for (i=0; i<N; i++) {
  476.         GlobalFree(pHands[i]);
  477.     };
  478.     return result;
  479. };
  480.  
  481.  
  482. // Make an Array containing two elements
  483. // Input: Obj1 - HGLOBAL to object1
  484. //          Obj2 - HGLOBAL to object2
  485. // Output: HGLOBAL to array {Obj1, Obj2}
  486. // NOTE: Obj1 and Obj2 are freed by this function
  487. HGLOBAL    MakeArray2(HGLOBAL    Obj1, HGLOBAL Obj2)
  488. {
  489.     HGLOBAL    tab[2];
  490.     tab[0]=Obj1;
  491.     tab[1]=Obj2;
  492.     return MakeArrayN(tab, 2);
  493. }
  494.  
  495. // Make an Array containing two elements
  496. // Input: Obj1 - HGLOBAL to object1
  497. //          Obj2 - HGLOBAL to object2
  498. //          Obj3 - HGLOBAL to object3
  499. // Output: HGLOBAL to array {Obj1, Obj2, Obj3}
  500. // NOTE: Obj1 Obj2 and Obj3 are freed by this function
  501. HGLOBAL    MakeArray3(HGLOBAL    Obj1, HGLOBAL Obj2, HGLOBAL Obj3)
  502. {
  503.     HGLOBAL    tab[3];
  504.     tab[0]=Obj1;
  505.     tab[1]=Obj2;
  506.     tab[2]=Obj3;
  507.     return MakeArrayN(tab, 3);
  508. }
  509.  
  510. // Make an Array containing two elements
  511. // Input: Obj1 - HGLOBAL to object1
  512. //          Obj2 - HGLOBAL to object2
  513. //          Obj3 - HGLOBAL to object3
  514. //          Obj4 - HGLOBAL to object4
  515. // Output: HGLOBAL to array {Obj1, Obj2, Obj3, Obj4}
  516. // NOTE: Obj1 Obj2 Obj3, Obj4 are freed by this function
  517. HGLOBAL    MakeArray4(HGLOBAL    Obj1, HGLOBAL Obj2, HGLOBAL Obj3, HGLOBAL Obj4)
  518. {
  519.     HGLOBAL    tab[4];
  520.     tab[0]=Obj1;
  521.     tab[1]=Obj2;
  522.     tab[2]=Obj3;
  523.     tab[3]=Obj4;
  524.     return MakeArrayN(tab, 4);
  525. }
  526.  
  527.